<!DOCTYPE html>
<html lang="zh-CN">
<!-- 作者：邓伟，网站：https://mqtt.vb6.pro -->

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MQTT客户端 | VBMAN</title>
    <link rel="stylesheet" href="css/style.css?v=15">
    <script src="lib/mqtt.min.js"></script>
    <script src="lib/vue.global.js"></script>
</head>

<body>
    <div id="app">
        <audio id="soundSend" src="assets/sound/send.mp3" preload="auto" style="display: none"></audio>
        <audio id="soundReceive" src="assets/sound/rec.mp3" preload="auto" style="display: none"></audio>
        <audio id="soundJoin" src="assets/sound/jinlai.mp3" preload="auto" style="display: none"></audio>
        <audio id="soundLeave" src="assets/sound/likai.mp3" preload="auto" style="display: none"></audio>
        <div class="toast" v-if="toast.show" :class="toast.type">
            {{ toast.message }}
        </div>
        <div class="header">
            <div class="title-row">
                <h2>
                    <img src="favicon.ico" class="title-icon" alt="Logo">
                    MQTT客户端
                </h2>
            </div>
            <div class="controls-row">
                <button class="control-btn sound-toggle" @click="toggleSound" :class="{ 'muted': !soundEnabled }"
                    :title="soundEnabled ? '关闭提示音' : '开启提示音'">
                    <svg v-if="soundEnabled" viewBox="0 0 24 24" width="24" height="24">
                        <path
                            d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"
                            fill="currentColor" />
                    </svg>
                    <svg v-else viewBox="0 0 24 24" width="24" height="24">
                        <path
                            d="M3 9v6h4l5 5V4L7 9H3zm7-.17v6.34L7.83 13H5v-2h2.83L10 8.83zM16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"
                            fill="currentColor" />
                    </svg>
                </button>
                <button class="control-btn theme-toggle" @click="toggleTheme" :title="darkMode ? '切换到亮色主题' : '切换到暗色主题'">
                    <svg class="theme" v-if="!darkMode" width="24" height="24" viewBox="0 0 24 24" fill="none"
                        xmlns="http://www.w3.org/2000/svg">
                        <path
                            d="M21.5 14.0784C20.3003 14.7189 18.9301 15.0821 17.4751 15.0821C12.7491 15.0821 8.91792 11.2509 8.91792 6.52485C8.91792 5.06986 9.28105 3.69968 9.92163 2.5C5.66765 3.49698 2.5 7.31513 2.5 11.8731C2.5 17.1899 6.8101 21.5 12.1269 21.5C16.6849 21.5 20.503 18.3324 21.5 14.0784Z"
                            stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
                    </svg>
                    <svg class="theme" v-else width="24" height="24" viewBox="0 0 24 24" fill="none"
                        xmlns="http://www.w3.org/2000/svg">
                        <path
                            d="M12 16C14.2091 16 16 14.2091 16 12C16 9.79086 14.2091 8 12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16Z"
                            stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
                        <path d="M12 4V2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
                            stroke-linejoin="round" />
                        <path d="M12 22V20" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
                            stroke-linejoin="round" />
                        <path d="M20 12H22" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
                            stroke-linejoin="round" />
                        <path d="M2 12H4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
                            stroke-linejoin="round" />
                        <path d="M17.657 6.343L19.071 4.929" stroke="currentColor" stroke-width="1.5"
                            stroke-linecap="round" stroke-linejoin="round" />
                        <path d="M4.929 19.071L6.343 17.657" stroke="currentColor" stroke-width="1.5"
                            stroke-linecap="round" stroke-linejoin="round" />
                        <path d="M17.657 17.657L19.071 19.071" stroke="currentColor" stroke-width="1.5"
                            stroke-linecap="round" stroke-linejoin="round" />
                        <path d="M4.929 4.929L6.343 6.343" stroke="currentColor" stroke-width="1.5"
                            stroke-linecap="round" stroke-linejoin="round" />
                    </svg>
                </button>
                <button class="control-btn sidebar-toggle" @click="toggleSidebar"
                    :title="sidebarVisible ? '隐藏侧边栏' : '显示侧边栏'">
                    <svg viewBox="0 0 24 24" width="24" height="24">
                        <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" fill="currentColor" />
                    </svg>
                </button>
            </div>
        </div>
        <div class="sidebar-overlay" :class="{ 'visible': sidebarVisible }" @click="toggleSidebar"></div>
        <div class="main-container">
            <div class="server-info" :class="{ 'visible': sidebarVisible }">
                <div class="info-item" @click="copyText(serverInfo.broker)" title="点击复制服务器地址">
                    <span class="label">服务器地址:</span>
                    <span class="value">{{ serverInfo.broker }}</span>
                </div>
                <div class="info-item" @click="copyText(topic)" title="点击复制订阅主题">
                    <span class="label">订阅主题:</span>
                    <span class="value">{{ topic }}</span>
                </div>
                <div class="info-item" @click="copyText(clientId)" title="点击复制客户端ID">
                    <span class="label">客户端ID:</span>
                    <span class="value">{{ clientId }}</span>
                </div>
                <div class="collapsible-panel">
                    <div class="panel-header" @click="portsExpanded = !portsExpanded"
                        :class="{ 'expanded': portsExpanded }">
                        <span>端口信息</span>
                        <svg class="chevron-icon" viewBox="0 0 24 24" width="18" height="18">
                            <path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2" fill="none"
                                stroke-linecap="round" stroke-linejoin="round" />
                        </svg>
                    </div>
                    <div class="panel-content" :class="{ 'expanded': portsExpanded }">
                        <div class="info-item" @click="copyText(serverInfo.tcp)" title="点击复制TCP端口">
                            <span class="label">TCP 端口:</span>
                            <span class="value">{{ serverInfo.tcp }}</span>
                        </div>
                        <div class="info-item" @click="copyText(serverInfo.ws)" title="点击复制WebSocket端口">
                            <span class="label">WebSocket 端口:</span>
                            <span class="value">{{ serverInfo.ws }}</span>
                        </div>
                        <div class="info-item" @click="copyText(serverInfo.ssl)" title="点击复制SSL/TLS端口">
                            <span class="label">SSL/TLS 端口:</span>
                            <span class="value">{{ serverInfo.ssl }}</span>
                        </div>
                        <div class="info-item" @click="copyText(serverInfo.wss)" title="点击复制WebSocket Secure端口">
                            <span class="label">WebSocket Secure 端口:</span>
                            <span class="value">{{ serverInfo.wss }}</span>
                        </div>
                        <div class="info-item" @click="copyText(serverInfo.quic)" title="点击复制QUIC端口">
                            <span class="label">QUIC 端口:</span>
                            <span class="value">{{ serverInfo.quic }}</span>
                        </div>
                    </div>
                </div>
                <div class="info-item subscribers-info">
                    <span class="label">订阅人数:</span>
                    <span class="value">{{ subscriberCount }}</span>
                </div>
                <div class="connection-status" :class="{ 'connected': connected }">
                    连接状态: {{ connected ? '已连接' : '未连接' }}
                </div>
                <div class="warning-block">
                    <b>警告：</b>
                    本站仅用于提供VBMAN的桌面MQTT客户端对接测试使用，服务器是
                    <a href="https://www.emqx.com/zh/mqtt/public-mqtt5-broker" target="_blank">
                        杭州映云科技有限公司（EMQ）
                    </a>
                    提供的公开免费测试服务器，你须遵守国家法律，洁身自好，切勿以身试法发布违法内容，否则后果自负。
                </div>
                <div class="info-block text-center" style="display: flex;justify-content: space-around;">
                    <a href="https://gitee.com/woeoio/mqtt.vb6.pro" target="_blank">下载WEB源码</a>
                    <a href="https://doc.vb6.pro" target="_blank">等待VB6源码</a>
                </div>
            </div>
            <div class="chat-container">
                <div class="messages" ref="messagesContainer">
                    <div v-for="(msg, index) in messages" :key="index" :class="['message-wrapper', msg.type]">
                        <img :src="msg.type === 'sent' ? 'assets/user-self.svg' : 'assets/user-other.svg'"
                            class="avatar" :alt="msg.type === 'sent' ? '我' : '其他人'">
                        <div class="message-block">
                            <div class="message-info">
                                <span class="sender-id">{{ msg.type === 'sent' ? '我' : msg.senderId }}</span>
                                <span class="message-time">{{ formatTime(msg.timestamp) }}</span>
                            </div>
                            <div class="message-content">
                                <pre>{{ msg.content }}</pre>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="input-container">
                    <input type="text" v-model="newMessage" @keyup.enter="sendMessage" placeholder="输入消息...回车">
                    <button @click="sendMessage">发送</button>
                </div>
            </div>
        </div>
    </div>
    <script src="js/app.js?v=15"></script>
    <script defer src="https://tj.a-vi.com/script.js" data-website-id="b8c01e03-17ae-43e5-ad6d-54a535bdf169"></script>
</body>

</html>